/**
 * 常用插件初始化
 * @link https://ym2.cleverstone.top
 * @copyright Copyright (c) 2020 Yii Manager Software LLC
 */

// angular应用初始化
+function (global, angular, ym2, toastr, jQuery, swal, yii, ymSpinner, layui, UE, _, Sortable, ym2Encrypt, xmSelect) {

    "use strict";

    var ym2Module;

    // 注册angular-select2插件模块
    try {
        angular.module("ui.select2");
        angular.module("ym2.upload");
        ym2Module = angular.module("ym2.module", ["ui.select2", "ym2.upload"]);
    } catch (e) {
        ym2Module = angular.module("ym2.module", []);
    }

    // 注册服务依赖
    ym2Module.factory("ym2", function () {
        // ym2
        return ym2 || {};
    }).factory("toastr", function () {
        // toastr
        return toastr || {};
    }).factory("jQuery", function () {
        // jQuery3
        return jQuery || {};
    }).factory("swal", function () {
        // sweetalert
        return swal || {};
    }).factory('yii', function () {
        // yii2
        return yii || {};
    }).factory("ymSpinner", function () {
        // spinner
        return ymSpinner || {};
    }).factory("layui", function () {
        // layui
        return layui || {};
    }).factory("ue", function () {
        // ueditor
        return UE || {};
    }).factory("lodash", function () {
        // lodash
        return _ || {};
    }).factory("Sortable", function () {
        return Sortable || {};
    }).factory("ym2Encrypt", function () {
        return ym2Encrypt || {};
    }).factory("xmSelect", function () {
        return xmSelect || {};
    });

    // 注册常用过滤器
    ym2Module.filter("toHtml", ['$sce', function ($sce) {
        // 过滤器:过滤html
        return function (value) {
            return $sce.trustAsHtml(String(value));
        };
    }]).filter("default", function () {
        // 过滤器:默认值
        return function (value, defaultVal) {
            return value || defaultVal;
        };
    }).filter("toUpper", function () {
        return function (value) {
            if (value) {
                return String(value).toUpperCase();
            } else {
                return "文件";
            }
        };
    });

    // 自定义指令
    ym2Module.directive('ym2Page', ["$compile", function ($compile) {
        // 分页指令
        return {
            restrict: 'A',
            replace: true,
            scope: false,
            link: function (scope, element, attrs) {
                scope.$watch(
                    function (scope) {
                        return scope.$eval(attrs.ym2Page);
                    },
                    function (value) {
                        element.html(value);
                        $compile(element.contents())(scope);
                    }
                );
            }
        };
    }]).directive('onFinishRender', ["$timeout", function ($timeout) {
        // 监听ng-repeat执行完成指令
        return {
            restrict: 'A',
            link: function (scope, element, attr) {
                if (scope.$last === true) {
                    $timeout(function () {
                        // ev-repeat-finished
                        scope.$emit(attr.onFinishRender);
                    });
                }
            }
        };
    }]).directive('stringToNumber', function () {
        // 当前input控件是number时，自动转换ngModel的数据类型。
        return {
            require: 'ngModel',
            link: function (scope, element, attrs, ngModel) {
                // 输出转换为字符串
                ngModel.$parsers.push(function (value) {
                    if (value !== void 0 && value !== null) {
                        return '' + value;
                    } else {
                        return '';
                    }
                });
                // 格式化
                ngModel.$formatters.push(function (value) {
                    return parseFloat(value);
                });
            }
        };
    }).directive("layuiFormRender", ["layui", function (layui) {
        // 解决layui表单中多选/开关/单选不兼容angular问题
        return {
            restrict: 'A',
            require: "ngModel",
            link: function (scope, element, attrs, ngModel) {
                scope.$watch(
                    function () {
                        return ngModel.$modelValue;
                    },
                    function () {
                        layui.form.render();
                    }
                );
            },
        };
    }]).directive("ym2Laydate", ["layui", function (layui) {
        // laydate日期插件渲染
        return {
            restrict: 'A',
            link: function (scope, element, attr) {
                var range = attr.ym2Range;
                var type = attr.ym2Type;
                var options = {
                    elem: element,
                    type: type,
                    calendar: true, // 展示节日
                    done: function (value, date, endDate) {
                        /* 触发input事件 */
                        jQuery(this.elem).val(value).trigger("change");
                    },
                };

                if (Number(range) === 1) {
                    options.range = '/';
                    // 2.8+
                    // 是否开启日期范围选择时的区间联动标注模式，该模式必须开启 range 属性才能生效。
                    options.rangeLinked = true;
                } else if (type === 'datetime') {
                    // 2.8+
                    options.fullPanel = true;
                }

                layui.laydate.render(options);
            }
        };
    }]).directive("ym2BootstrapPlugin", function () {
        // bootstrap插件初始化
        return {
            restrict: "A",
            link: function (scope, element, attr) {
                var pluginName = attr.ym2BootstrapPlugin;
                var config = attr.pluginConfig || "";
                try {
                    config && eval("config=" + config);
                } catch (e) {
                    config = "";
                }

                if (config !== "") {
                    element[pluginName](config);
                } else {
                    element[pluginName]();
                }
            },
        };

    }).directive("xmSelect", ["xmSelect", "ym2", function (xmSelect, ym2) {
        // xm-select angular数据双向绑定
        return {
            restrict: "A",
            scope: false,
            require: "ngModel",
            link: function (scope, element, attr, controller) {
                var options = scope.$eval(attr.xmSelect);
                var instance;
                var changeValue;
                var initValue;
                var valueField;
                if (options.prop && options.prop.value) {
                    valueField = options.prop.value;
                } else {
                    valueField = "value";
                }

                options.el = "#" + attr.id;
                options.on = function (data) {
                    if (options.radio) {
                        changeValue = "";
                    } else {
                        changeValue = [];
                    }
                    data.arr.forEach(function (value) {
                        if (options.radio) {
                            changeValue = value[valueField];
                        } else {
                            changeValue.push(value[valueField]);
                        }
                    });

                    controller.$setViewValue(changeValue);
                };

                instance = xmSelect.render(options);
                initValue = instance.getValue(options.radio ? "valueStr" : "value");
                instance.oldValue = initValue;
                controller.$setViewValue(initValue);
                scope.$watch(function () {
                    return controller.$modelValue;
                }, function (newVal, oldVal) {
                    newVal = newVal || [];
                    if (ym2.typeOf(newVal) !== "array") {
                        newVal = new Array(newVal);
                    }

                    instance.setValue(newVal);
                });

            },
        };
    }]).directive("ym2Star", ["layui", "ym2", function (layui, ym2) {
        return {
            restrict: "A",
            scope: false,
            require: "ngModel",
            link: function (scope, element, attr, controller) {
                var eleDom = element[0];
                var options = scope.$eval(attr.ym2Star) || {};
                var rate = layui.rate;

                //格式化配置
                options.elem =  eleDom;
                options.value = controller.$modelValue;
                if ( options.setText ) {
                    var customTxt = options.setText;
                    options.setText = function (value) {
                        this.span.text(customTxt[value] || ( value + "星"));
                    };
                }

                if ( !options.theme ) {
                    options.theme = ym2.getAppThemeColor();
                }

                //更新vm
                options.choose = function (value) {
                    controller.$setViewValue(value);
                };

                scope.$watch(function () {
                    return controller.$modelValue;
                }, function (newVal) {
                    newVal = newVal || 0;
                    options.value = newVal;
                    //更新视图
                    rate.render(options);
                });
            },
        };
    }]);

    // 定义http拦截器
    ym2Module.factory("httpInterceptor", ["$q", function ($q) {
        // http拦截器
        return {
            'responseError': function (response) { // 错误拦截
                return $q.reject(response);
            },
            'response': function (response) {     // 响应拦截
                return response;
            },
            'request': function (config) {        // 请求拦截
                // 当时请求方法是`POST`时,自动携带[csrf]令牌,并自动参数序列化.
                var method = config.method;
                var bodyParams = config.data || {};
                if (method.toUpperCase() === 'POST') {
                    bodyParams[yii.getCsrfParam()] = yii.getCsrfToken();

                    var contentType = config.headers['Content-Type'];
                    if (contentType && ym2.typeOf(contentType) === 'string') {
                        // application/x-www-form-urlencoded
                        if (contentType.indexOf('application/x-www-form-urlencoded') !== -1) {
                            config.data = jQuery.param(bodyParams);
                        }

                        // application/json
                        if (contentType.indexOf('application/json') !== -1) {
                            config.data = JSON.stringify(bodyParams);
                        }

                        // ...
                    }
                    // 其他`content-type`不用处理，如：undefined、multipart/form-data
                }

                return config;
            },
            'requestError': function (config) {    // 请求错误拦截
                return $q.reject(config);
            }
        };
    }]).config(["$httpProvider", function ($httpProvider) {
        $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
        $httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

        // 添加拦截器
        $httpProvider.interceptors.push('httpInterceptor');
    }]);


    // 全局定义ym2应用
    global.ym2App = angular.module("ym2.app", ["ym2.module", "ngFileUpload"]);

    // 禁止a标签href中, 以下协议标记unsafe
    global.ym2App.config(['$compileProvider', function ($compileProvider) {
        if ($compileProvider.imgSrcSanitizationWhitelist) $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|s?ftp|mailto|tel|webcal|local|file|data|blob|javascript):/);
        if ($compileProvider.aHrefSanitizationWhitelist) $compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|s?ftp|mailto|tel|webcal|local|file|data|blob|javascript):/);
    }]);

}(
    window,
    window.angular,
    window.ym2,
    window.toastr,
    window.jQuery,
    window.swal,
    window.yii,
    window.ymSpinner,
    window.layui,
    window.UE,
    window._,
    window.Sortable,
    window.ym2Encrypt,
    window.xmSelect
);

// 常用插件初始化
-function (global, top, jQuery, toastr, layui, UE, ym2Fullscreen) {

    "use strict";

    // 设置select2主题
    if (typeof jQuery.fn !== 'undefined' && jQuery.fn.select2) {
        /* Sets select2 bootstrap4-theme */
        jQuery.fn.select2.defaults.set("theme", "bootstrap4");
        jQuery.fn.select2.defaults.set("language", "zh-CN");
    } else {
        console.warn("The select2 plugin theme and i18n are not set.");
    }

    // 初始化toastr
    if (jQuery && typeof toastr !== 'undefined' && toastr.options) {
        toastr.options.closeButton = false;
        toastr.options.progressBar = false;
        toastr.options.timeOut = 3000; // How long the toast will display without user interaction
        toastr.options.extendedTimeOut = 3000; // How long the toast will display after a user hovers over it
        toastr.options.showMethod = 'slideDown';
        // toastr.options.showMethod = 'fadeIn';
        toastr.options.hideMethod = 'fadeOut';
        toastr.options.showEasing = "swing";
        toastr.options.hideEasing = "linear";
        toastr.options.closeMethod = 'fadeOut';
        toastr.options.closeDuration = 300;
        toastr.options.positionClass = 'toast-top-center';
    } else {
        console.warn("The toastr plugin is not initialized.");
    }

    // IMG查看全图
    if (jQuery && top.layui) {
        jQuery(document).on("click", "[ym2-full-image]", function () {
            var that = this;
            var igDom = jQuery(that).closest("[ym2-image-group]");
            var start = 0;
            var data = [];

            if (igDom.length) {
                igDom.find("[ym2-full-image]").each(function (index, currentDom) {
                    if (currentDom === that) {
                        start = index;
                    }

                    var $currentDom = jQuery(currentDom);
                    data.push({
                        "alt": $currentDom.attr("alt") || "",
                        "src": $currentDom.attr("src"),
                        "thumb": $currentDom.attr("thumb") || $currentDom.attr("src"),
                    });
                });
            } else {
                var $that = jQuery(that);
                data.push({
                    "alt": $that.attr("alt") || "",
                    "src": $that.attr("src"),
                    "thumb": $that.attr("thumb") || $that.attr("src"),
                });
            }

            top.layui.layer.photos({
                photos: {
                    "title": "查看大图",
                    "start": start,
                    "data": data,
                },
            });
        });
    } else {
        console.warn("The large image is not bound.");
    }

    // 初始化ueditor
    if (jQuery && UE) {
        var ueditorContianer = {};
        jQuery("[ym2-ueditor]").each(function () {
            var id = this.id;
            var config = this.getAttribute("ym2-ueditor") || "{}";
            try {
                eval("config=" + config);
            } catch (e) {
                config = {};
            }

            config.initialFrameWidth = config.initialFrameWidth || config.width || "100%";
            config.initialFrameHeight = config.initialFrameHeight || config.height || 500;
            config.autoHeightEnabled = config.autoHeightEnabled || false;

            delete config.width;
            delete config.height;

            ueditorContianer[id] = UE.getEditor(id, config);
        });

        // 获取已初始化的ueditor实例
        UE.getInstanceById = function (id) {
            return ueditorContianer[id] || null;
        };
    } else {
        console.warn("Baidu Editor did not initialize the binding.");
    }

    // 解决layui表单有些控件无法触发$setter问题
    if (layui) {
        layui.form.on("checkbox(ym2_form_checkbox)", function (data) {
            // checkbox trigger change
            layui.jquery(data.elem).trigger("change");
        });
        layui.form.on("switch(ym2_form_switch)", function (data) {
            // switch trigger change
            layui.jquery(data.elem).trigger("change");
        });
        layui.form.on("radio(ym2_form_radio)", function (data) {
            // radio trigger change
            layui.jquery(data.elem).trigger("change");
        });
    } else {
        console.warn("The layui form control is not bound to angular js.");
    }

    // 窗口全屏
    if (jQuery && ym2Fullscreen) {
        // 监听
        jQuery(document).on("click", ".ym2AppScreen", function (e) {
            if (ym2Fullscreen.isFullscreen()) {
                // 关闭
                ym2Fullscreen.fullClose().then(function () {
                    global.localStorage.removeItem("ym2_is_fullscreen");
                });
            } else {
                // 打开
                ym2Fullscreen.fullScreen().then(function () {
                    global.localStorage.setItem("ym2_is_fullscreen", "yes");
                });
            }
        });
    } else {
        console.warn("The JS full-screen plug-in is not bound.");
    }
    // 文本复制,支持dom异步渲染
    if (jQuery && layui) {
        jQuery(document).on("click", "[ym2-clipboard]", function (e) {
            var lay = layui.lay;
            var layer = layui.layer;
            var txt = jQuery(this).attr("ym2-clipboard");

            lay.clipboard.writeText({
                text: txt,
                done: function() {
                    alert('😘复制成功!');
                    /*layer.msg("已复制", {
                        offset: "16px",
                    });*/
                },
                error: function() {
                    alert('🥵复制失败!');
                    /*layer.msg("复制失败", {
                        offset: "16px",
                    });*/
                }
            });

        });

    } else {
        console.warn("The clipboard isn't initialized.")
    }
}(window, top, window.jQuery, window.toastr, window.layui, window.UE, window.ym2Fullscreen);